package xrc.service.impl;

import com.alibaba.fastjson.JSONObject;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple2;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xrc.contract.MaskVoteContract;
import xrc.domain.ECGroup;
import xrc.domain.ECPoint;
import xrc.domain.MaskVote;
import xrc.domain.User;
import xrc.mapper.UserMapper;
import xrc.service.TestService;

import java.math.BigInteger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

@Service
public class TestImpl implements TestService {

    //调用mapper层方法，将user传递下去
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MaskVoteImpl contract;
    ECGroup ecgroup = new ECGroup();
    //    ECPoint g = new ECPoint(ecgroup.x1, ecgroup.y1);
    ECPoint h = ecgroup.randompoint();
    MaskVote maskVote = new MaskVote();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    int n = 2; //总人数
    int t = 1; //门限值

    //添加联合公钥
    @Override
    public List<Object> addY(JSONObject user) throws Exception {

//        String username = user.getString("username");
        String voteItem = user.getString("voteitem");
        System.out.println("voteItem = " + voteItem);
        String voters = user.getString("voterlist");
        System.out.println("voters = " + voters);

        String voteId = userMapper.findSqlId(voteItem);  //获取投票事项id
        System.out.println("获取投票事项id = " + voteId);
        /*User user1 = userMapper.findId(username);

        String loginId = String.valueOf(user1.getId());
        //String loginId = String.valueOf(userMapper.findId(username));  //获取发起投票用户id
        System.out.println("获取发起投票用户id = " + loginId);*/
        String voterList = voters.substring(1, voters.length() - 1);
        System.out.println("substring = " + voterList);
        String[] strings = voterList.split(", ");  //获取所有参与者
        int[] idList = new int[strings.length];

        ECPoint[] A0List = new ECPoint[strings.length];   //从智能合约里读取的第i个参与者的A值数组的第一个值
        for (int t = 0; t < strings.length; t++) {
            User voter = userMapper.findId(strings[t]);//获取每个参与者id
            System.out.println("voter = " + voter);
            Integer voterIdInt = voter.getId();
            String voterIdString = String.valueOf(voterIdInt);

            idList[t] = voterIdInt;
            ECPoint ecPoint = contract.getA(voterIdString);
            A0List[t] = ecPoint;

        }
        ECPoint Y = maskVote.Y(A0List, ecgroup);
        System.out.println("ecgroup = " + ecgroup);
        List<String> YList = new ArrayList<>();
        YList.add(Y.toString());
        for (String s : YList) {
            System.out.println("YList = " + s);
        }

        JSONObject result = new JSONObject();   //创建返回给前端状态
        List<Object> resultList = new ArrayList<>();    //生成结果状态列表

        //将YList上传至智能合约 联合公钥
        TransactionReceipt transactionReceipt = contract.addY(voteId, YList);
        MaskVoteContract client = contract.Client();
        Tuple2<String, List<String>> addYInput = client.getAddYInput(transactionReceipt);
        if (addYInput != null){
            result.put("result","添加成功");
            result.put("code","200");
        }else {
            result.put("result","添加失败");
            result.put("code","400");
        }
        resultList.add(result);
        System.out.println(transactionReceipt);
        return resultList;
    }

    //上传加密选票
    @Override
    public List<Object> addE(JSONObject event) throws Exception {

//        String username = event.getString("username");
        String voteItem = event.getString("voteitem");
        String voters = event.getString("voterlist");

        String voterList = voters.substring(1, voters.length() - 1);
        System.out.println("substring = " + voterList);
        String[] strings = voterList.split(", ");  //获取所有参与者
        for (String voter : strings) {
            System.out.println("参与者为 = " + voter);
        }
        String voteId = userMapper.findSqlId(voteItem);  //获取投票事项id

        /*User user = userMapper.findId(username);
        System.out.println("user = " + user);
        String loginId = String.valueOf(user.getId());
        System.out.println("loginId = " + loginId);*/

        //调用密码算法的mul_en_vote()接口
        int[] idList = new int[strings.length];
        ECPoint[][] en_vote_list = new ECPoint[strings.length][2];
        for (int i = 0; i < strings.length; i++) {
            User voter = userMapper.findId(strings[i]);//获取每个参与者id
            Integer voterIdInt = voter.getId();
            String voterIdString = String.valueOf(voterIdInt);
            idList[i] = voterIdInt;
            List SecVote = contract.getSecVote(voterIdString, voteId);

            for (int j = 0; j < SecVote.size(); j++) {

                System.out.println("SecVote.get(j) = " + SecVote.get(j).toString());
                String SecVoteString = SecVote.get(j).toString();
                String[] str = SecVoteString.split(",");
                BigInteger o1 = new BigInteger(str[0], 16);
                BigInteger o2 = new BigInteger(str[1], 16);
                ECPoint ecPoint = new ECPoint(o1, o2);
                System.out.println("ecPoint = " + ecPoint);
                en_vote_list[i][j % 2] = ecPoint;
            }

            System.out.println("en_vote_list[0][0] = " + en_vote_list[0][0]);
            System.out.println("en_vote_list[0][1] = " + en_vote_list[0][1]);
            System.out.println("en_vote_list[1][0] = " + en_vote_list[1][0]);
            System.out.println("en_vote_list[1][1] = " + en_vote_list[1][1]);
            System.out.println("en_vote_list[1][1] = " + en_vote_list[2][0]);
            System.out.println("en_vote_list[1][1] = " + en_vote_list[2][1]);

        }

        ECPoint[] mixedVoteList = maskVote.mul_en_vote(en_vote_list, ecgroup);
        for (ECPoint ecPoint : mixedVoteList) {
            System.out.println("ecPoint = " + ecPoint);
        }
        List<String> mixedVote = new ArrayList<>();

        for (int i = 0; i < mixedVoteList.length; i++) {
            mixedVote.add(mixedVoteList[i].toString());
        }
        for (String s : mixedVote) {
            System.out.println("mixedVote = " + s);
        }

        JSONObject result = new JSONObject();   //创建返回给前端状态
        List<Object> resultList = new ArrayList<>();    //生成结果状态列表

        //将相乘结果E存进智能合约
        TransactionReceipt transactionReceipt = contract.addMixedVote(voteId, mixedVote);
        MaskVoteContract client = contract.Client();
        Tuple2<String, List<String>> addMixedVoteInput = client.getAddMixedVoteInput(transactionReceipt);
        if (addMixedVoteInput != null){
            result.put("result","添加成功");
            result.put("code","200");
        }else {
            result.put("result","添加失败");
            result.put("code","400");
        }
        resultList.add(result);
        return resultList;
    }

    @Override
    public List<Object> getSum(JSONObject event) throws Exception {

        String voteItem = event.getString("voteitem");
        String voterList = event.getString("voterlist");
        String[] strings = voterList.split(", ");  //获取所有参与者

        String voteId = userMapper.findSqlId(voteItem);  //获取投票事项id

        ECPoint E0 = contract.getE0(voteId);

        ECPoint[] en_g_R_list = new ECPoint[strings.length];
        System.out.println("strings.length = " + strings.length);
        for (int i = 0; i < strings.length; i++) {
            User user1 = userMapper.findId(strings[i]);
            String id1 = String.valueOf(user1.getId());
            ECPoint GRi = contract.getg_R(id1, voteId);

            en_g_R_list[i] = GRi;
        }
        for (ECPoint ecPoint : en_g_R_list) {
            System.out.println("ecPoint = " + ecPoint);
        }

        JSONObject result = new JSONObject();   //创建返回给前端状态
        List<Object> resultList = new ArrayList<>();    //生成结果状态列表

        //计算总票数并存放进数据库
        int sum = maskVote.sum(ecgroup, en_g_R_list, h, E0);
        System.out.println("sum = " + sum);
        Integer sumResult = userMapper.updateSum(sum, voteItem);
        if (sumResult != 0){
            result.put("result","投票成功，请查看投票结果");
            result.put("code","200");
        }else {
            result.put("result","投票失败");
            result.put("code","500");
        }

        resultList.add(result);
        return resultList;
    }
}
